/* 
 * Advanced Foundation Classes
 * Copyright (C) 2000/2004  Fabio Rotondo - Andrea Galimberti
 *  
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *  
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *  
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include "widgets.h"


static const char class_name[] = "EasyGUI";



// {{{ afc_easygui_internal_init_widgets ( egui ) 
/*
@node afc_easygui_internal_init_widgets

DESCRIPTION: this functions adds all the widgets to EasyGUI as commands to be recognized by the parser.

@endnode
*/
int afc_easygui_internal_init_widgets ( EasyGUI * easygui )
{
	int afc_res = AFC_ERR_NO_ERROR;

	F_IN()

	// Sets the info tag in the DCM
	afc_dynamic_class_master_set_tag ( easygui->commands, AFC_DYNAMIC_CLASS_MASTER_TAG_INFO, easygui );

	afc_cmd_parser_set_tag ( easygui->parser, AFC_CMD_PARSER_TAG_DEFAULT_TEMPLATE, "NAME/K SPACE/K BORDER/K TIP/K LONGTIP/K EXPAND/S FILL/S HFILL/S VFILL/S TABTITLE/K TABICON/K INFO/K KEYEVENTS/K DNDDEST/K" );

	afc_res = afc_dynamic_class_master_add ( easygui->commands, "window", NULL, afc_easygui_internal_window_new_instance, afc_easygui_internal_window_del_instance, NULL );

	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "eqrows", NULL, afc_easygui_internal_eqrows_new_instance, afc_easygui_internal_eqrows_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "eqcols", NULL, afc_easygui_internal_eqcols_new_instance, afc_easygui_internal_eqcols_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "rows", NULL, afc_easygui_internal_rows_new_instance, afc_easygui_internal_rows_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "cols", NULL, afc_easygui_internal_cols_new_instance, afc_easygui_internal_cols_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "frame", NULL, afc_easygui_internal_frame_new_instance, afc_easygui_internal_frame_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "tabs", NULL, afc_easygui_internal_tabs_new_instance, afc_easygui_internal_tabs_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "label", NULL, afc_easygui_internal_label_new_instance, afc_easygui_internal_label_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "separator", NULL, afc_easygui_internal_separator_new_instance, afc_easygui_internal_separator_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "button", NULL, afc_easygui_internal_button_new_instance, afc_easygui_internal_button_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "checkbutton", NULL, afc_easygui_internal_checkbutton_new_instance, afc_easygui_internal_checkbutton_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "radiobutton", NULL, afc_easygui_internal_radiobutton_new_instance, afc_easygui_internal_radiobutton_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "entry", NULL, afc_easygui_internal_entry_new_instance, afc_easygui_internal_entry_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "combo", NULL, afc_easygui_internal_combo_new_instance, afc_easygui_internal_combo_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "clist", NULL, afc_easygui_internal_clist_new_instance, afc_easygui_internal_clist_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "scrolledwindow", NULL, afc_easygui_internal_scrolledwindow_new_instance, afc_easygui_internal_scrolledwindow_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "drawingarea", NULL, afc_easygui_internal_drawingarea_new_instance, afc_easygui_internal_drawingarea_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "toolbar", NULL, afc_easygui_internal_toolbar_new_instance, afc_easygui_internal_toolbar_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "menubar", NULL, afc_easygui_internal_menubar_new_instance, afc_easygui_internal_menubar_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "menu", NULL, afc_easygui_internal_menu_new_instance, afc_easygui_internal_menu_del_instance, NULL );
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "optmenu", NULL, afc_easygui_internal_optmenu_new_instance, afc_easygui_internal_optmenu_del_instance, NULL );

#ifdef DONT_WORK
	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "tclist", NULL, afc_easygui_internal_tclist_new_instance, afc_easygui_internal_tclist_del_instance, NULL );

	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "text", NULL, afc_easygui_internal_text_new_instance, afc_easygui_internal_text_del_instance, NULL );

	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "scale", NULL, afc_easygui_internal_scale_new_instance, afc_easygui_internal_scale_del_instance, NULL );

	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "image", NULL, afc_easygui_internal_image_new_instance, afc_easygui_internal_image_del_instance, NULL );

	afc_res = afc_res & afc_dynamic_class_master_add ( easygui->commands, "tree", NULL, afc_easygui_internal_tree_new_instance, afc_easygui_internal_tree_del_instance, NULL );
#endif


	/* add more widgets here */

	F_OUT()

	return ( afc_res );
}
// }}}
// {{{ afc_easygui_widget_connect_signal ( dyn, w, event, func_name, sig_id, default_func ) ****
/*
@node afc_easygui_widget_connect_signal
	Connects the widget event with the user provided function callback

	INPUTS:	
		- dyn		- Dynamic Class to connect the event to
		- w		- GtkWidget to connect event to (if NULL it will be set to ewidget->gtk_handle)
		- event		- Event Name (GTK Name)
		- func_name	- User selected function name
		- sig_id	- Place where to store Signal value
		- default_func	- Pointer to the plugin-provided default function
				  NOTE: if it is NULL, then the event will be stored in the callback dictionary
					but the function will not be connected.

	SEE ALSO:	afc_easygui_widget_store_function()
@endnode
*/
int afc_easygui_widget_connect_signal ( DynamicClass * dyn, GtkWidget * w, char * event, char * func_name, guint * sig_id, GtkSignalFunc default_func )
{
	EasyGUIWidgetData * ewidget;
	EasyGUIContext * context = WIDGET_GET_CONTEXT ( dyn );
	// EasyGUI * easygui = context->egui;
	guint signal = 0;

	F_IN()

	// If the func_name is not specified, we do not link the event to the widget
	if ( func_name == NULL ) return ( AFC_ERR_NO_ERROR );

	WIDGET_GET_EWIDGET ( dyn, ewidget );
	
	/* connect the signal to the GTK widget */
	if ( w == NULL ) w = ewidget->gtk_handle;

	if ( default_func ) signal = g_signal_connect ( G_OBJECT ( w ), event, G_CALLBACK ( default_func ), dyn );
	if ( sig_id ) *sig_id = signal;

	F_OUT()

	return ( afc_easygui_widget_store_function ( context, dyn, event, func_name ) );
}
// }}}
// {{{ afc_easygui_widget_get_callback ( dyn, event_name ) ****
/*
	Returns the specific event binded to the given evente_name

	NOTE: using a very low-level approach
*/
void * afc_easygui_widget_get_callback ( DynamicClass * dyn, char * event_name )
{
	if ( dyn->private_vars == NULL ) return ( NULL );

	return ( afc_dictionary_get ( dyn->private_vars, event_name ) );
}
// }}}
// {{{ afc_easygui_widget_parse_default_params ( egui ) ****
int afc_easygui_widget_parse_default_params ( EasyGUI * easygui )
{
	EasyGUIDefaultParams * pars = easygui->def_params;
	char * s;

	F_IN()
	
	pars->name  = afc_cmd_parser_arg_get_by_name ( easygui->parser, "NAME" );
	if ( ( pars->name != NULL ) && ( strcasecmp ( pars->name, "NULL" ) == 0 ) ) pars->name = NULL;

	s = afc_cmd_parser_arg_get_by_name ( easygui->parser, "SPACE" );
	if ( s == NULL ) s = "0";
	pars->space = atoi ( s );

	s = afc_cmd_parser_arg_get_by_name ( easygui->parser, "BORDER" );
	if ( s == NULL ) s = "0";
	pars->border = atoi ( s );

	pars->tip  	= afc_cmd_parser_arg_get_by_name ( easygui->parser, "TIP" );
	pars->longtip  	= afc_cmd_parser_arg_get_by_name ( easygui->parser, "LONGTIP" );
	pars->tab_title	= afc_cmd_parser_arg_get_by_name ( easygui->parser, "TABTITLE" );
	pars->tab_icon	= afc_cmd_parser_arg_get_by_name ( easygui->parser, "TABICON" );
	pars->info	= afc_cmd_parser_arg_get_by_name ( easygui->parser, "INFO" );

	// PATCH: remove these two lines and use only HFILL and VFILL
	pars->expand  = ( short ) ( int ) afc_cmd_parser_arg_get_by_name ( easygui->parser, "EXPAND" );
	pars->fill    = ( short ) ( int ) afc_cmd_parser_arg_get_by_name ( easygui->parser, "FILL" );

	if ( pars->expand == FALSE ) pars->expand = ( BOOL ) ( int ) afc_cmd_parser_arg_get_by_name ( easygui->parser, "VFILL" );
	if ( pars->fill == FALSE ) pars->fill = ( BOOL ) ( int ) afc_cmd_parser_arg_get_by_name ( easygui->parser, "HFILL" );

	pars->key_events = afc_cmd_parser_arg_get_by_name ( easygui->parser, "KEYEVENTS" );

	F_OUT()

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_widget_standard_free ( dyn ) ****
int afc_easygui_widget_standard_free ( DynamicClass * dyn )
{
	EasyGUIWidgetData * ewd;

	F_IN()

	if ( dyn == NULL ) return ( AFC_ERR_INVALID_POINTER );

	WIDGET_FREE_EWIDGET ( dyn, ewd );

	afc_dynamic_class_delete ( dyn );

	F_OUT()

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_widget_make_glist ( egui, items ) ***
/*
	This function takes a delimited string as input and generates a new GList
	NOTE: you have to free the returned GList!
*/
GList * afc_easygui_widget_make_glist ( EasyGUI * easygui, char * items )
{
	GList * lst = NULL;
	char * s;

	F_IN()

	if ( items == NULL ) return ( NULL );

	// TODO: lock the stringnode resource

	afc_stringnode_split ( easygui->int_data->snode, items, easygui->int_data->delimiters );

	s = afc_stringnode_first ( easygui->int_data->snode );
	while ( s != NULL )
	{
		lst = g_list_append ( lst, afc_string_dup ( s ) );
		s = afc_stringnode_next ( easygui->int_data->snode );
	}

	afc_stringnode_clear ( easygui->int_data->snode );

	// TODO: free the stringnode resource

	F_OUT()

	return ( lst );
}
// }}}
// {{{ afc_easygui_widget_create_label ( dyn, text, iconname, horientation )
/*
@node afc_easygui_widget_create_label
	       NAME: afc_easygui_widget_create_label ( easygui, text, iconname, horientation )

	   SYNOPSIS: GtkWidget * afc_easygui_widget_create_label ( EasyGUI * easygui, char * text, char * iconname, int horientation );

	DESCRIPTION: This function creates a label + icon combo. Both /text/ and /iconname/ may be NULL.

	   SEE ALSO: afc_easygui_widget_get_horient()
@endnode
*/
GtkWidget * afc_easygui_widget_create_label ( DynamicClass * dc, char * text, char * iconname, int horientation )
{
	GtkWidget * icon;
	GtkWidget * box;
	GtkWidget * label;
	GtkWidget * first, * second;
	EasyGUI   * easygui	= dc->info;

	F_IN()

	if ( ( iconname == NULL )  && ( text == NULL ) ) return ( NULL );

	if ( iconname == NULL )
		return ( gtk_label_new ( text ) );

	if ( afc_easygui_preload_icon ( easygui, iconname ) != AFC_ERR_NO_ERROR )
	{
			AFC_LOG ( AFC_LOG_ERROR, AFC_EASYGUI_ERR_NO_PIXMAP, "Pixmap not found", iconname );
			return ( NULL );
	}

	icon = afc_easygui_load_icon ( easygui, iconname, GTK_ICON_SIZE_BUTTON );

	if ( text == NULL ) return ( icon );

	label = gtk_label_new ( "-" );
	gtk_label_set_markup ( GTK_LABEL ( label ), text );

	if ( ( horientation == AFC_EASYGUI_HORIENT_TOP ) || ( horientation == AFC_EASYGUI_HORIENT_BOTTOM ) )
	{
		box = gtk_vbox_new ( TRUE, 0 );

		if ( horientation == AFC_EASYGUI_HORIENT_TOP )
		{
			first  = label;
			second = icon;
		} else {
			first  = icon;
			second = label;
		}

	} else {
		box = gtk_hbox_new ( TRUE, 0 );

		if ( horientation == AFC_EASYGUI_HORIENT_LEFT )
		{
			first  = label;
			second = icon;
		} else {
			first  = icon;
			second = label;
		}
	}

	gtk_box_pack_start ( GTK_BOX ( box ), first,  FALSE, FALSE, 3 );
	gtk_box_pack_start ( GTK_BOX ( box ), second, FALSE, FALSE, 3 );

	WIDGET_SET_ICON ( dc, icon );

	F_OUT()

	return ( box );
}
// }}}


// --------------------------------------------------------------------------------------------------------------------
// INTERNAL FUNCTIONS
// --------------------------------------------------------------------------------------------------------------------
